﻿@using Resource;
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta http-equiv="Expires" content="0">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-control" content="no-cache">
    <meta http-equiv="Cache" content="no-cache">
    @{
        await Html.RenderPartialAsync("/Views/Shared/_LayoutScript.cshtml");
    }
    @{
        await Html.RenderPartialAsync("/Views/Shared/_StyleCss.cshtml");
    }

    <script src="/lib/later/later.js?v=@DateTime.Now.Ticks"></script>
    <script src="/lib/xlsx/xlsx.full.min.js?v=@DateTime.Now.Ticks"></script>
    <link href="/css/LduYield.css?v=@DateTime.Now.Ticks" rel="stylesheet" />
    <title>LduYield</title>
    <style type="text/css">
        /*报表样式*/
        html, body {
            background: url(../images/ProcessCapacity/bgwhite.png) no-repeat;
            background-size: cover;
            font-size: .16rem;
            color: #ffffff;
            position: relative;
            width: 100%;
            height: 100%;
            font-family: myFirstFont !important;
            color: black;
        }

        .hover-image {
            display: none;
            position: absolute;
            top: 20px;
            left: 0;
            width: 35vw;
            border: 1px solid #ccc;
            background: #fff;
            z-index: 999;
        }

        .warn-flag:hover .hover-image {
            display: block;
        }

        .rightTop {
            background-color: #f7fdff;
        }

        .dropbtn, button {
            background-color: #0aa9cd;
        }

        #query > button {
            background-color: #0aa9cd;
            border: 2px solid #0aa9cd;
        }

        .dropdown-content {
            background-color: #12bed0;
        }

        .Zebra {
            background-color: #e5ecff;
        }

        .ZebraNo {
            background-color: #e8f1f9;
        }

        .ZebraTo {
            background-color: #ffffff;
        }

        .warn {
            background-color: #ffcccc;
        }

        .note {
            color: red;
            font-size: 0.15rem;
            font-weight: bolder;
        }

        .warning {
            background-color: #ffaf0078;
            border-color: transparent;
        }

        .danger {
            background-color: #ff1f0078;
            border-color: transparent;
        }
        /*END*/

        #Tab1 {
            height: 9.6rem;
            background-image: url('../images/loading.gif');
            background-size: 0.8rem 0.8rem;
            background-repeat: no-repeat;
            background-position: center;
        }

        #yield_tbody {
            white-space: nowrap;
            margin: 0;
            border: none;
            border-collapse: collapse;
        }

        #yield_tbody tr,
        #yield_tbody td {
            border: 1px solid #cecece
        }

        .DataSheet th{
            font-size: 0.18rem;
        }

        .DataSheet td {
            font-size: 0.17rem;
        }

        .linkstyle {
            color: blue;
            font-weight: bolder;
        }

        /*明细模态*/
        .mode_confirm {
            border-radius: 0.1rem;
            position: absolute;
            z-index: 99;
            height: 100vh;
            width: 100vw;
            background: #ffffff;
            display: none;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

        .mode_confirm > .mode_detail > div > label {
            color: black;
        }

        .detail {
            color: black;
            background-color: #f7fdff;
            height: 3rem;
            width: 100%;
        }

        .mode_close {
            color: #007bff;
            float: right;
            font-size: 0.18rem;
            font-weight: bold;
            margin: 0.1rem 0;
            padding: 3px 3px 0px 0px;
        }

        .mode_close:hover {
            color: red;
            font-size: 0.2rem;
            font-weight: bold;
        }

        /*end*/

        .mode_detail {
            height: calc((100% - 0.65rem) * (1/2));
            width: calc(100% - 0.2rem);
            margin: 0 auto;
            margin: 0 0.1rem;
            /* border: 1px solid red; */
        }

    </style>
</head>
<body class="fill-parent" style="overflow-y: hidden; color: black;">
    <div class="main">
        <div class="header">
            <div class="header-left fl">
                <img src="/images/logo.png?v=@DateTime.Now.Ticks" class="scaled-image" draggable="false" oncontextmenu="return false;" ondragstart="return false;" />
            </div>
            <div class="btn">
                <spn>
                    <div id="query">
                        <div class="dropdown">
                            <button class="dropbtn">@Label.Desktop</button>
                            <div class="dropdown-content">
                                <a class="menudropdown" href=@Html.Raw($"https://dashboard.li.lumentuminc.net/API/DesktopApp/Dashboard.exe?v={DateTime.Now.Ticks}") download>@Label.Local</a>
                                <a class="menudropdown" href=@Html.Raw($"https://dashboard.li.lumentuminc.net/API/DesktopApp/Dashboard_lnk.zip?v={DateTime.Now.Ticks}") download>@Label.Shortcut</a>
                            </div>
                        </div>
                        <div class="dropdown">
                            <button class="dropbtn">@Label.Language</button>
                            <div class="dropdown-content">
                                <a class="menudropdown" onclick="setLanguageCookie('@Const.CNLANGUAGE')">@Label.Chinese</a>
                                <a class="menudropdown" onclick="setLanguageCookie('@Const.USLANGUAGE')">@Label.English</a>
                            </div>
                        </div>
                        <button class="modalBtn dimension">@Label.Full</button>
                    </div>
                </spn>
            </div>
            <div class="header-center fl">
                <div class="header-title"></div>
                <div class="header-img"></div>
            </div>
            <div class="header-right fl" id="time"></div>
            <div class="header-bottom fl"></div>
        </div>
        <div class="center">
            <div class="center-left fl">
                <div class="left-top rightTop border" id="report_id" >
                    <div class="title note">
                        <span class="warn-flag" style="color:red; position: relative;">ℹ️<img src="../images/lot.png?v=@DateTime.Now.Ticks" class="hover-image" /></span>
                        @Label.Note_LduYield
                    </div>
                    <div id="board" class="chart">
                        <div class="query">
                            <input type="datetime-local" id="startdate" name="startdate" placeholder="@Label.Start@Label.Time">
                            <span class="exampleInputProject tle">@Label.To</span>
                            <input type="datetime-local" id="enddate" name="enddate" placeholder="@Label.Start@Label.End">
                            <span class="titleinput tle">Type:</span>
                            <select id="cmb_type" name="ProdType" placeholder="select prodtype">
                                <option value="ALL">@Label.ALL</option>
                                <option value="Normal">@Label.Fresh</option>
                                <option value="Rework">@Label.Rework</option>
                                <option value="RMA">@Label.RMA</option>
                            </select>
                            <span class="titleinput tle">ProjCode:</span>
                            <select id="cmb_projcode" placeholder="select ProjCode">
                                <option value="">@Label.PleaseSelect</option>
                            </select>
                            <button id="btn_query" class="btn btn-primary  btn-sm col-md-12" type="button" onclick="getdate()">@Label.Query</button>
                        </div>
                        <div id="Tab1">
                            <div id="table-container"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="mode_confirm">
            <span class="mode_close">关闭×</span>
            <div style="height: 0.3rem; margin: 0.15rem 0;">
                <span class="process_name" style="font-size:0.25rem;color:#007bff;font-weight:bold;line-height:0.3rem;padding-left: 0.15rem;"></span>
            </div>
            <div class="mode_detail" id="inputchart"></div>
            <div class="mode_detail" id="failuremodechart"></div>
        </div>
    </div>

    <script type="text/javascript" href="?v=@DateTime.Now.Ticks">
        $(".mode_confirm").css("display", "none");
        $('.mode_close').click(function () {
            $(".mode_confirm").css("display", "none");
            //$(".mode_detail").empty();
        });
        $(document).ready(function () {
            var whei = $(window).height();
            $("html").css({ fontSize: whei / 12.5 });
            $(window).resize(function () {
                if ($(".dimension").text() == "@Html.Raw(Label.Full)") {
                    var whei = $(window).height();
                    $("html").css({ fontSize: whei / 12.5 });
                }
                else {
                    var whei = $(window).width();
                    $("html").css({ fontSize: whei / 22 })
                }
            });

            function numberToUpperCase(number) {
                var uppercaseMonths = [
                    '一月', '二月', '三月', '四月', '五月', '六月',
                    '七月', '八月', '九月', '十月', '十一月', '十二月'
                ];
                return uppercaseMonths[number - 1];
            }
            var myDate = new Date();
            var result = numberToUpperCase(myDate.getMonth() + 1);
            $('.header-title').html("@Html.Raw(Label.Board_LduYield)");
            function getTime() {
                var myDate = new Date();
                var myYear = myDate.getFullYear();
                var myMonth = myDate.getMonth() + 1;
                var myToday = myDate.getDate();
                var myDay = myDate.getDay();
                var myHour = myDate.getHours();
                var myMinute = myDate.getMinutes();
                var mySecond = myDate.getSeconds();
                var week = ['@Label.Sunday', '@Label.Monday', '@Label.Tuesday', '@Label.Wednesday', '@Label.Thursday', '@Label.Friday', '@Label.Saturday'];
                var nowTime;

                nowTime = myYear + '-' + fillZero(myMonth) + '-' + fillZero(myToday) + '&nbsp;&nbsp;' + fillZero(myHour) + ':' + fillZero(myMinute) + ':' + fillZero(mySecond) + '&nbsp;&nbsp;' + week[myDay] + '&nbsp;&nbsp;';
                $('#time').html(nowTime);
            };

            function fillZero(str) {
                var realNum;
                if (str < 10) {
                    realNum = '0' + str;
                } else {
                    realNum = str;
                }
                return realNum;
            }
            setInterval(getTime, 1000);
            // 设置全屏
            $('.dimension').on('click', function (e) {
                var element = document.documentElement;
                 if ($(".dimension").text() == "@Html.Raw(Label.Full)") {
                    // 判断浏览器设备类型
                    if (element.requestFullscreen) {
                        element.requestFullscreen();
                    } else if (element.mozRequestFullScreen) {       //兼容火狐
                        element.mozRequestFullScreen();
                    } else if (element.webkitRequestFullscreen) {    //兼容谷歌
                        element.webkitRequestFullscreen();
                    } else if (element.msRequestFullscreen) {        //兼容IE
                        element.msRequestFullscreen();
                    }
                    $(".dimension").text("@Html.Raw(Label.Exit + Label.Full)");
                } else {
                    if (document.exitFullscreen) {
                        document.exitFullscreen();
                    } else if (document.mozCancelFullScreen) {
                        document.mozCancelFullScreen();
                    } else if (document.webkitCancelFullScreen) {
                        document.webkitCancelFullScreen();
                    } else if (document.msExitFullscreen) {
                        document.msExitFullscreen();
                    }
                    $(".dimension").text("@Html.Raw(Label.Full)");
                }
            });

            // 开始时间改变时限制结束时间
            $('#startdate').on('change', function () {
                var startDate = new Date($(this).val());
                var endDate = new Date($('#enddate').val());
                startDate.setDate(startDate.getDate() + 1);
                var minEndDate = startDate.toISOString().split('T')[0];
                $('#enddate').attr('min', minEndDate);
                if (endDate < startDate) {
                    $('#enddate').val($(this).val());
                }
            });
            // 结束时间改变时限制开始时间
            $('#enddate').on('change', function () {
                var startDate = new Date($('#startdate').val());
                var endDate = new Date($(this).val());
                endDate.setDate(endDate.getDate() - 1);
                var maxStartDate = endDate.toISOString().split('T')[0];
                $('#startdate').attr('max', maxStartDate);
                if (startDate > endDate) {
                    $('#startdate').val($(this).val());
                }
            });
        });

        function setDateRange(){
            var now = new Date();
            now.setMinutes(now.getMinutes() + 1);
            var hours = now.getHours();
            var minutes = now.getMinutes();

            var startDate = new Date();
            startDate.setDate(startDate.getDate() - 7);
            startDate.setHours(7, 0, 0, 0);
            var endDate = new Date();
            endDate.setHours(hours, minutes, 0, 0);
            var startdatetime = startDate.toLocaleDateString('sv-SE') + 'T' + startDate.toTimeString().slice(0, 5);
            $('#startdate').val(startdatetime);
            var enddatetime = endDate.toLocaleDateString('sv-SE') + 'T' + endDate.toTimeString().slice(0, 5);
            $('#enddate').val(enddatetime);
        }

        //报表导出
        var exportDdata = function(type){
            const book = XLSX.utils.book_new();
            const sheet = XLSX.utils.json_to_sheet(Tab.report);
            XLSX.utils.book_append_sheet(book, sheet);
            XLSX.writeFile(book,`${type}.xlsx`);
        }

        function loadingshow() {
            $('#btn_query').prop('disabled', true);
            $('#Tab1').css('background-image', 'url("../images/loading.gif")');
            $('#Tab1').css('background-size', '0.8rem 0.8rem');
            $('#Tab1').css('background-repeat', 'no-repeat');
            $('#Tab1').css('background-position', 'center');
        }
        function loadingnone() {
            $('#btn_query').prop('disabled', false);
            $('#Tab1').css('background-image', 'none');
        }

        $(function () {
            var projectsele = $("#cmb_projcode");
            function getHeaderParam() {
                return {
                    start: $('#startdate').val().replace("T", " "),
                    end: $('#enddate').val().replace("T", " ")
                };
            }

            function loadProjCodeDropdown(callback) {
                var pam = {
                    header_key: JSON.stringify(getHeaderParam())
                };
                $.ajax({
                    type: "POST",
                    url: api + '/ReportAction/GetLduYieldProjCode',
                    data: pam,
                    async: false,
                    dataType: "json",
                    success: function (data) {
                        var selectdata = data.ReturnData;
                        projectsele.empty();
                        projectsele.append("<option value=''>@Html.Raw(Label.PleaseSelect)...</option>");

                        if (!selectdata || selectdata.length === 0) {
                            projectsele.append("<option>@Html.Raw(Label.No + Label.Correlation + Label.Data)</option>");
                            return;
                        }

                        $.each(selectdata, function (key, value) {
                            projectsele.append($('<option>', {
                                value: value.value,
                                text: value.text
                            }));
                        });

                        var first = projectsele.find('option').not('[value=""]').first().val();
                        if (first) {
                            projectsele.val(first).trigger('change');
                        }

                        if (typeof callback === 'function') {
                            callback();
                        }
                    }
                });
            }
            setDateRange();
            $('#cmb_type').val('ALL'); 
            loadProjCodeDropdown(getdate); 

            $('#startdate, #enddate').on('change', function () {
                loadProjCodeDropdown(getdate);
            });

            $('#cmb_type, #cmb_projcode').on('change', function () {
                getdate();
            });
        });

        //定时查询
        later.date.localTime();
        //const schedule = later.parse.text('every 30 seconds')
        const schedule = later.parse.text('every 1 hour');
        later.setInterval(() => {
            console.log("执行任务：", new Date().toLocaleTimeString());
            setDateRange();
            getdate();
        }, schedule);

        //yielddetail轮循
        let index = 0;
        setInterval(() => {
            if ($('.mode_confirm').is(':visible')) {
                const ids = Tab.Table.map(r => r.PROCESS_ID).filter(Boolean);
                if (!ids.length) return;
                if (index >= ids.length) index = 0;
                yielddetail(ids[index]);
                index = (index + 1) % ids.length;
            }
        }, 25 * 60 * 1000); 

        //获取数据
        var Tab;
        var getdate = function () {
            var header_key = {
                start:  $('#startdate').val().replace("T", " "),
                end: $('#enddate').val().replace("T", " ")
            };
            var pam = {};
            pam.proj_code = $('#cmb_projcode').val();
            pam.type = $("#cmb_type").val();
            pam.header_key = JSON.stringify(header_key);
            $('#table-container').empty();
            loadingshow();
            $.ajax({
                type: "POST",
                url: api + "/ReportAction/GetLduYield",
                data: pam,
                dataType: "json",
                async: true,
                success: function (dt) {
                    loadingnone();
                    Tab = dt.ReturnData;
                    if(Tab.Table.length > 0){
                        var tableHTML = `
                        <table class="DataSheet" border="1" style="width: 100%; height: 100%;">
                        <thead>
                            <tr>
                                <th>Station</th>
                                <th>Input</th>
                                <th>Fail</th>
                                <th>Output</th>
                                <th>PrimeYield</th>
                                <th>FinalYield</th>
                                <th>FailureMode</th>
                                <th>PrimeReject</th>
                                <th>RetestPass</th>
                                <th>FinalFail</th>
                                <th>PrimeRejectRate</th>
                                <th>FinalRejectRate</th>
                            </tr>
                        </thead>
                        <tbody id="yield_tbody"></tbody>
                        <tfoot>
                            <tr>
                                <th id="sum" colspan="4"></th>
                                <th id="primeyield"></th>
                                <th id="finalyield"></th>
                                <th></th>
                                <th></th>
                                <th></th>
                                <th></th>
                                <th></th>
                                <th></th>
                            </tr>
                        </tfoot>
                        </table>`;
                        $('#table-container').html(tableHTML);
                        var tableRows = "";
                        var primeyield = 1, finalyield = 1;
                        var yield_dt = Tab.Table;

                        yield_dt.forEach(function (row, i) {
                            var zebracro = i % 2 === 0 ? 'class="zebracro"' : '';
                            var isHeaderRow = row.ROW_ID && parseInt(row.ROW_ID) > 0;
                            if (isHeaderRow) {
                                tableRows += `<tr ${zebracro}>
                                    <td class="tabletd linkstyle" rowspan="${row.ROWSPAN}" onclick="yielddetail('${row.PROCESS_ID}')" >${row.PROCESS_ID}<span class="warn-flag" style="color:red" title="点击查看趋势图ℹ️">ℹ️</span></td>
                                    <td class="tabletd" rowspan="${row.ROWSPAN}">${row.INPUT_QTY}</td>
                                    <td class="tabletd" rowspan="${row.ROWSPAN}">${(row.INPUT_QTY || 0) - (row.OUTPUT_QTY || 0)}</td>
                                    <td class="tabletd" rowspan="${row.ROWSPAN}">${row.OUTPUT_QTY}</td>
                                    <td class="tabletd" rowspan="${row.ROWSPAN}">${row.PRIME_YIELD}</td>
                                    <td class="tabletd" rowspan="${row.ROWSPAN}">${row.FINAL_YIELD}</td>
                                    <td>${row.FAILURE_MODE}</td>
                                    <td class="tabletd">${row.PRIME_REJECT}</td>
                                    <td class="tabletd">${row.RETEST_PASS}</td>
                                    <td class="tabletd">${row.FINAL_FAIL}</td>
                                    <td class="tabletd">${row.PRIME_REJECT_RATE}</td>
                                    <td class="tabletd">${row.FINAL_REJECT_RATE}</td>
                                </tr>`;
                                var primeFloat = parseFloat(row.PRIME_YIELD.replace('%', '')) / 100 || 1;
                                var finalFloat = parseFloat(row.FINAL_YIELD.replace('%', '')) / 100 || 1;
                                primeyield *= primeFloat;
                                finalyield *= finalFloat;
                            } else {
                                tableRows += `
                                <tr ${zebracro}>
                                    <td>${row.FAILURE_MODE}</td>
                                    <td class="tabletd">${row.PRIME_REJECT}</td>
                                    <td class="tabletd">${row.RETEST_PASS}</td>
                                    <td class="tabletd">${row.FINAL_FAIL}</td>
                                    <td class="tabletd">${row.PRIME_REJECT_RATE}</td>
                                    <td class="tabletd">${row.FINAL_REJECT_RATE}</td>
                                </tr>`;
                            }
                        });
                        $('#yield_tbody').html(tableRows);
                        $('#sum').text("@Html.Raw(Label.Summary)");
                        $('#primeyield').text((primeyield * 100).toFixed(2) + "%");
                        $('#finalyield').text((finalyield * 100).toFixed(2) + "%");
                    }
                }
            });
        }

        function yielddetail(process)
        {
            var projcode = $('#cmb_projcode option:selected').text();
            $(".mode_confirm").css("display", "block");
            $(".process_name").text(`${projcode}：${process}`);
            inputchart(process,Tab.Table1);
            failuremodechart(process,Tab.Table1);
        }

        function inputchart(process,data)
        {
            var projcode = $('#cmb_projcode option:selected').text();
            const chartDom = document.getElementById('inputchart');
            if (chartDom) {
                echarts.dispose(chartDom);
            }
            const myChart = echarts.init(chartDom);
            const seenDate = new Set();
            const stagefpyarray = [];
            data.filter(d => d.PROCESS_ID === process).forEach(row => {
                const date = row.DATE.split('T')[0].replaceAll('-', '');
                if (seenDate.has(date)) return;
                seenDate.add(date);
                const input = row.INPUT_QTY;
                const output = row.OUTPUT_QTY;
                const failure = input - output;
                const fpy = input > 0 ? output / input : 0;
                stagefpyarray.push({
                    DATE_TIME: date,
                    FIRST_INPUT: input,
                    TOTAL_FAILURE: failure,
                    FPY: fpy
                });
            });
            const categories = stagefpyarray.map(item => item.DATE_TIME);
            const firstInput = stagefpyarray.map(item => item.FIRST_INPUT);
            const totalFailure = stagefpyarray.map(item => item.TOTAL_FAILURE);
            const fpy = stagefpyarray.map(item => parseFloat((item.FPY * 100).toFixed(2)));
            //设置图表
            myChart.setOption({
                title: {
                    text: `${projcode} ${process} Input Chart`,
                    left: 'center',
                    textStyle: {
                        fontSize: '0.2rem',
                        fontWeight: 'bold'
                    }
                },
                tooltip: {
                    trigger: 'axis',
                    axisPointer: { type: 'cross' }
                },
                toolbox: {
                    feature: {
                        dataView: { show: true, readOnly: false },
                        magicType: { show: true, type: ['line', 'bar'] },
                        restore: { show: true },
                        saveAsImage: {
                            show: true,
                            name: `${projcode}_${process}_Input_Chart`
                        }
                    }
                },
                legend: {
                    top: '8%',
                    data: ['FIRST_INPUT', 'TOTAL_FAILURE', 'FPY'],
                    textStyle: {
                        fontSize: '0.16rem',
                        fontWeight: 'bold'
                    }
                },
                grid: {
                    top: '20%',
                    left: '4%',
                    right: '4%'
                },
                xAxis: {
                    type: 'category',
                    data: categories,
                    axisLabel: { rotate: 45 }
                },
                yAxis: [
                {
                    type: 'value',
                    name: 'Input',
                    position: 'left',
                    yAxisIndex: 0,
                    splitLine: { show: false }
                },
                {
                    type: 'value',
                    name: 'FPY(%)',
                    position: 'right',
                    yAxisIndex: 1,
                    min: 0,
                    max: 100,
                    axisLabel: {
                        formatter: '{value}%'
                    }
                }],
                dataZoom: [
                    {
                        type: 'inside',
                        yAxisIndex: 1,
                        zoomLock: false
                    },
                    {
                        type: 'slider',
                        yAxisIndex: 1,
                        zoomLock: false,
                        right: 1,
                        width: 10
                    }
                ],
                series: [
                {
                    name: 'FIRST_INPUT',
                    type: 'bar',
                    data: firstInput,
                    barWidth: '30%'
                },
                {
                    name: 'TOTAL_FAILURE',
                    type: 'bar',
                    data: totalFailure,
                    barWidth: '30%'
                },
                {
                    name: 'FPY',
                    type: 'line',
                    yAxisIndex: 1,
                    smooth: false,
                    lineStyle: {
                        width: 3,
                        color: '#FFA500'
                    },
                    itemStyle: {
                        color: '#FFA500',
                        borderWidth: 2,
                        borderColor: '#FF4500'
                    },
                    symbolSize: 8,
                    data: fpy,
                    tooltip: {
                        valueFormatter: (value) => value.toFixed(2) + '%'
                    }
                }]
            });
            window.addEventListener('resize', () => {
                myChart.resize();
            });
        }

        function failuremodechart(process,data)
        {
            var projcode = $('#cmb_projcode option:selected').text();
            const failureModeMap = new Map();
            const xAxisSet = new Set();
            data.filter(d => d.PROCESS_ID === process).forEach(row => {
                if (!row.FAILURE_MODE || row.FAILURE_MODE.trim() === '') return;
                const date = row.DATE.split('T')[0].replaceAll('-', '');
                xAxisSet.add(date);
                const mode = row.FAILURE_MODE;
                if (!failureModeMap.has(mode)) failureModeMap.set(mode, []);
                failureModeMap.get(mode).push({
                    dateTime: date,
                    failRate: parseFloat(row.PRIME_REJECT_RATE)
                });
            });
            const xAxisData = Array.from(xAxisSet).sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
            const sortedEntries = Array.from(failureModeMap.entries()).sort((a, b) => {
                const avgA = a[1].reduce((sum, v) => sum + parseFloat(v.failRate), 0) / a[1].length;
                const avgB = b[1].reduce((sum, v) => sum + parseFloat(v.failRate), 0) / b[1].length;
                return avgB - avgA;
            });
            const sortedFailureModeMap = new Map(sortedEntries);
            const colors = ['#ff0000', '#efdf00', '#00008b', '#6b8e23', '#008b8b', '#ff00ff', '#ff8c00', '#4682b4', '#8031a7', '#a0522d'];
            let index = 0;
            const seriesData = [];
            const generateGradientColors = (baseColor) => [
                echarts.color.lift(baseColor, 0.4),
                echarts.color.lift(baseColor, -0.4)
            ];
            sortedFailureModeMap.forEach((values, failureMode) => {
                const colorGradient = generateGradientColors(colors[index % colors.length]);
                const dataMap = new Map(values.map(item => [item.dateTime, item.failRate]));
                const failRates = xAxisData.map(date => dataMap.get(date) || "0.00");
                seriesData.push({
                    name: failureMode,
                    type: 'line',
                    stack: 'total',
                    smooth: false,
                    showSymbol: false,
                    emphasis: { focus: 'series' },
                    lineStyle: {
                      width: 0,
                      color: colors[index % colors.length]
                    },
                    itemStyle: {
                      color: colors[index % colors.length]
                    },
                    areaStyle: {
                      opacity: 0.8,
                      color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        { offset: 0, color: colorGradient[0] },
                        { offset: 1, color: colorGradient[1] }
                      ])
                    },
                    data: failRates
                });
              index++;
          });
          const chartDom = document.getElementById('failuremodechart');
          echarts.dispose(chartDom);
          const myChart = echarts.init(chartDom);
          myChart.setOption({
              title: {
                  text: `${projcode} ${process} Failure Mode Chart`,
                  left: 'center',
                  textStyle: {
                      fontSize: '0.2rem',
                      fontWeight: 'bold'
                  }
              },
              tooltip: {
                  trigger: 'axis',
                  axisPointer: { type: 'line' },
                  formatter: function (params) {
                      const date = params[0].axisValue;
                      const markerMap = {};
                      params.forEach(p => markerMap[p.seriesName] = p.marker);
                      const filtered = data.filter(d => d.DATE.split('T')[0].replaceAll('-', '') === date && d.PROCESS_ID === process && d.PRIME_REJECT > 0);
                      if (filtered.length === 0) return '';
                      const summary = filtered[0];
                      const failureModes = filtered;
                      let html = `<div style="padding:4px 8px;"><strong>Process By Failure Mode(${date})</strong></div>`;
                      html += `<table id ="failddet" style="border-collapse: collapse; width: 100%; font-size: 12px;">`;
                      //PROCESS 汇总行标题
                      html += `
                        <tr>
                            <th style="text-align:left;">Process</th>
                            <th>Input</th>
                            <th>Output</th>
                            <th>Fail</th>
                            <th>PrimeYield</th>
                            <th>RetestPass</th>
                            <th>FinalYield</th>
                        </tr>`;
                      // 汇总数据行
                      html += `
                        <tr>
                            <td>${summary.PROCESS_ID}</td>
                            <td>${summary.INPUT_QTY}</td>
                            <td>${summary.OUTPUT_QTY}</td>
                            <td>${summary.INPUT_QTY - summary.OUTPUT_QTY}</td>
                            <td>${summary.PRIME_YIELD}</td>
                            <td>${failureModes.reduce((sum, f) => sum + f.RETEST_PASS, 0)}</td>
                            <td>${summary.FINAL_YIELD}</td>
                        </tr>`;
                      // 子表标题行（FAILURE_MODE 合并三格）
                      html += `
                        <tr>
                            <th colspan="3">FailureMode</th>
                            <th>PrimeReject</th>
                            <th>PrimeRejectRate</th>
                            <th>RetestPass</th>
                            <th>FinalRejectRate</th>
                        </tr>`;
                      // 子项数据行
                      failureModes.forEach(d => {
                          const marker = markerMap[d.FAILURE_MODE] || '';
                          html += `
                            <tr>
                                <td colspan="3">${marker} ${d.FAILURE_MODE}</td>
                                <td>${d.PRIME_REJECT}</td>
                                <td>${d.PRIME_REJECT_RATE}</td>
                                <td>${d.RETEST_PASS}</td>
                                <td>${d.FINAL_REJECT_RATE}</td>
                            </tr>`;
                        });
                        html += `</table>`;
                        return html;
                    }
              },
              toolbox: {
                  feature: {
                      dataView: { show: true, readOnly: false },
                      magicType: { show: true, type: ['bar'] },
                      restore: { show: true },
                      saveAsImage: {
                          show: true,
                          name: `${projcode}_${process}_Failure_Mode_Chart`
                      }
                  }
              },
              legend: {
                  show: true,
                  top: '8%',
                  type: 'scroll',
                  width: '98%',
                  data: Array.from(sortedFailureModeMap.keys()),
                  orient: 'horizontal',
                  itemWidth: 12,
                  itemHeight: 12,
                  scrollDataIndex: 0,
                  pageIconSize: [16, 16],
                  pageIconColor: '#0aa9cd',
                  pageTextStyle: {
                      fontSize: '0.16rem'
                  },
                  textStyle: {
                      fontSize: '0.16rem',
                      fontWeight: 'bold'
                  }
              },
              grid: {
                  top: '20%',
                  left: '4%',
                  right: '3%'
              },
              xAxis: {
                  type: 'category',
                  data: xAxisData,
                  axisLabel: { rotate: 45 }
              },
              yAxis: {
                  type: 'value',
                  scale: true,
                  axisLabel: {
                      formatter: '{value}%'
                  }
              },
              series: seriesData
          });
          window.addEventListener('resize', () => {
              myChart.resize();
          });
        }

    </script>
</body>
</html>
